package repository

import (
	"gorm.io/gorm"

	"routeSrv/domain/model"
)

// 创建需要实现的接口
type IRouteRepository interface {
	// 初始化表
	InitTable() error
	// 根据 ID 查处找数据
	FindRouteByID(int64) (*model.Route, error)
	// 创建一条 Route 数据
	CreateRoute(*model.Route) (int64, error)
	// 根据 ID 删除一条 Route 数据
	DeleteRouteByID(int64) error
	// 修改一条数据
	UpdateRoute(*model.Route) error
	// 查找 Route 所有数据
	FindRouteList(page *model.Page) (int64, []model.Route, error)
}

type RouteRepository struct {
	mysqlDb *gorm.DB
}

// 创建 RouteRepository
func NewRouteRepository(db *gorm.DB) IRouteRepository {
	return &RouteRepository{mysqlDb: db}
}

// 初始化表
func (p *RouteRepository) InitTable() error {
	return p.mysqlDb.AutoMigrate(&model.Route{}, &model.RoutePath{})
}

// 根据 ID 查找 Route 信息
func (p *RouteRepository) FindRouteByID(routeID int64) (route *model.Route, err error) {
	route = &model.Route{}
	return route, p.mysqlDb.Preload("RoutePath").First(route, routeID).Error
}

// 创建 Route 信息
func (p *RouteRepository) CreateRoute(route *model.Route) (int64, error) {
	return route.ID, p.mysqlDb.Create(route).Error
}

// 根据 ID 删除 Route 信息
func (p *RouteRepository) DeleteRouteByID(routeID int64) error {
	tx := p.mysqlDb.Begin()
	//遇到问题回滚
	defer func() {
		if err := recover(); err != nil {
			tx.Rollback()
		}
	}()
	if tx.Error != nil {
		return tx.Error
	}

	//删除 Route 信息
	if err := tx.Where("id = ?", routeID).Delete(&model.Route{BaseModel: model.BaseModel{ID: routeID}}).Error; err != nil {
		tx.Rollback()
		return err
	}
	//删除 routepath 信息
	if err := tx.Where("route_id = ?", routeID).Delete(&model.RoutePath{RouteID: routeID}).Error; err != nil {
		tx.Rollback()
		return err
	}
	return tx.Commit().Error
}

// 更新 Route 信息
func (p *RouteRepository) UpdateRoute(route *model.Route) error {
	tx := p.mysqlDb.Begin()
	//遇到问题回滚
	defer func() {
		if err := recover(); err != nil {
			tx.Rollback()
		}
	}()
	if tx.Error != nil {
		return tx.Error
	}

	if err := tx.Model(&route).Updates(route).Error; err != nil {
		tx.Rollback()
		return err
	}
	for _, path := range route.RoutePath {
		if err := tx.Model(&path).Save(path).Error; err != nil {
			tx.Rollback()
			return err
		}
	}
	return tx.Commit().Error
}

// 获取结果集
func (p *RouteRepository) FindRouteList(page *model.Page) (total int64, routeList []model.Route, err error) {
	if result := p.mysqlDb.Model(&model.Route{}).Count(&total); result.Error != nil {
		return total, routeList, err
	}
	return total, routeList, p.mysqlDb.Model(&model.Route{}).Preload("RoutePath").Scopes(Paginate(page)).Find(&routeList).Error
}
